package mythread;

/**
 * @Auther: cty
 * @Date: 2020/1/6 12:18
 * @Description: 不安全1-1
 * 不安全概述：
 * （共享资源时，一个代理线程还未来得及“改”访问的工作空间中的资源，其他代理线程又去访问（读 或 改）该资源）
 * “未来得及”是网络延迟引起的，“其他代理线程又去访问”使得三个线程在临界值处判断对齐，
 * 三个线程都会再执行一次且打印结果不同，实际一个执行就够了，导致了多余操作。
 * @version: 1.0
 */
public class Ha_UnsafeTest1_1 implements Runnable{
    private int ticketsNum = 99;  //剩余车票数

    @Override
    public void run() {
        while(true){
            if(ticketsNum <= 0){  //【打印】
                break;  // 如果没票了就退出
            }else {
                //模拟网络延迟-导致判断对齐
                try {
                    // 临界值时a线程停留在这里，ticketsNum还未改变仍为临界值，b和c线程通过判断也进入这里，
                    // a线程sleep结束对【工作空间】中的ticketsNum（此时为1）操作变为0（抢到最后一张票），
                    // b线程sleep结束对同一【工作空间】中的ticketsNum（此时为0）操作变为-1，
                    // c线程sleep结束对同一【工作空间】中的ticketsNum（此时为-1）操作变为-2。
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"售出了 "+ticketsNum--+" 号票,剩余 "+ticketsNum+"张票");  //【打印】和【修改】
            }
        }
    }

    public static void main(String[] args) {
        //一份任务
        Ha_UnsafeTest1_1 ticket = new Ha_UnsafeTest1_1();
        //多个代理
        new Thread(ticket,"窗口1").start();  //第一个new Thread开辟工作空间，其他代理线程共享工作空间中的资源
        new Thread(ticket,"窗口2").start();
        new Thread(ticket,"窗口3").start();
    }
}

/* 结果
...
窗口2售出了 3 号票,剩余 2张票
窗口1售出了 2 号票,剩余 1张票
窗口3售出了 1 号票,剩余 0张票
窗口2售出了 0 号票,剩余 -1张票
窗口1售出了 -1 号票,剩余 -2张票
* */
